package com.onpositive.wiki3.db.impl;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.lang.ref.SoftReference;

import com.onpositive.wiki2.whole.model.ITemplateAccess;
import com.onpositive.wiki3.db.ICategoryAccess;
import com.onpositive.wiki3.db.IIdMapper;
import com.onpositive.wiki3.db.IRedirectAccess;
import com.onpositive.wiki3.db.ITextContentAccess;
import com.onpositive.wiki3.db.ITitleMapper;
import com.onpositive.wiki3.db.IWikiDB;

public class WikiDBImpl implements IWikiDB {

	protected File parentFile;
	protected SoftReference<ICategoryAccess> cs;
	protected SoftReference<ITextContentAccess> ts;
	protected SoftReference<IRedirectAccess> rs;
	private SoftReference<ITitleMapper> tm;

	public WikiDBImpl(String string) {
		parentFile = new File(string);
	}

	@Override
	public ICategoryAccess getCategoryAccessor() {
		if (cs == null) {
			return createCategoryAccess();
		}
		ICategoryAccess iCategoryAccess = cs.get();
		if (iCategoryAccess == null) {
			return createCategoryAccess();
		}
		return iCategoryAccess;
	}

	protected ICategoryAccess createCategoryAccess() {
		File fl = new File(parentFile, "relation.dat2");
		try {
			CategoryAccessImpl referent = new CategoryAccessImpl(fl, this);
			cs = new SoftReference<ICategoryAccess>(referent);
			return referent;
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
	}

	protected ITitleMapper createTitleAccess() {
		try {
			TitleMapperImpl referent = new TitleMapperImpl(this, parentFile);
			tm = new SoftReference<ITitleMapper>(referent);
			return referent;
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	protected ITextContentAccess createTextAccess() {
		try {
			TextContentAccess referent = new TextContentAccess(parentFile, this);
			ts = new SoftReference<ITextContentAccess>(referent);
			return referent;
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
	}

	@Override
	public ITextContentAccess getContentAccessor() {
		if (ts == null) {
			return createTextAccess();
		}
		ITextContentAccess iCategoryAccess = ts.get();
		if (iCategoryAccess == null) {
			return createTextAccess();
		}
		return iCategoryAccess;
	}

	@Override
	public IIdMapper getExtenalIdMapper() {
		return null;
	}

	@Override
	public ITitleMapper getTitleMapper() {
		if (tm == null) {
			return createTitleAccess();
		}
		ITitleMapper iCategoryAccess = tm.get();
		if (iCategoryAccess == null) {
			return createTitleAccess();
		}
		return iCategoryAccess;
	}

	@Override
	public IRedirectAccess getRedirectAccess() {
		if (rs == null) {
			RedirectAccessImpl referent = new RedirectAccessImpl(this,
					parentFile);
			rs = new SoftReference<IRedirectAccess>(referent);
			return referent;
		}

		IRedirectAccess iRedirectAccess = rs.get();
		if (iRedirectAccess == null) {
			RedirectAccessImpl referent = new RedirectAccessImpl(this,
					parentFile);
			rs = new SoftReference<IRedirectAccess>(referent);
			return referent;
		}
		return iRedirectAccess;
	}

	@Override
	public int size() {
		return getTitleMapper().size();
	}

	@Override
	public ITemplateAccess getTemlates() {
		File fl=new File(this.parentFile,"templates.lst");
		if (!fl.exists()){
			new MajorTemplatesBuilder().smartBuildMembers(this, fl);
		}
		ObjectInputStream is;
		try {
			is = new ObjectInputStream(new BufferedInputStream(new FileInputStream(fl)));
			return (ITemplateAccess) is.readObject();
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
		return null;
		
	}

	@Override
	public String getPath() {
		return parentFile.getAbsolutePath();
	}

}
